package com.ui.controls {
	import com.ui.core.PlaceState;
	import com.model.ListEvent;
	import com.model.ListModel;
	import com.model.ListState;
	import com.model.PageModel;
	import com.model.SelectionModel;
	import com.net.AssetData;
	import com.ui.cell.Cell;
	import com.ui.cell.CellData;
	import com.ui.containers.Panel;
	import com.ui.core.ScaleMode;
	import com.ui.data.AlertData;
	import com.ui.data.GirdData;
	import com.ui.data.TextInputData;
	import com.ui.drag.DragData;
	import com.ui.drag.DragModel;
	import com.ui.drag.DragState;
	import com.ui.drag.DragUiEvent;
	import com.ui.drag.IDragItem;
	import com.ui.drag.IDragSource;
	import com.ui.drag.IDragTarget;
	import com.ui.layout.GLayout;
	import com.ui.manager.UIManager;

	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Mouse;

	/**
	 * Game Gird
	 * 
	 * @author Cafe
	 * @version 20100719
	 */
	public class Gird extends Panel implements IDragTarget {
		public static const CELL_MOVE : String = "CELL_MOVE";
		public static const CELL_SPLIT : String = "CELL_SPLIT";
		protected var _girdData : GirdData;
		// 存储可以被互相拖动的ui的引用
		protected var _dragModel : DragModel;
		protected var _selectionModel : SelectionModel;
		protected var _model : ListModel;
		// 翻页功能
		protected var _pageModel : PageModel;
		protected var _cell : Class;
		protected var _cellWidth : int;
		protected var _cellHeight : int;
		// 所有的格子ui
		protected var _cells : Array;
		protected var _selectedCells : Array;
		protected var _dragData : DragData;
		protected var _dragCell : Cell;
		protected var _dragImage : Bitmap;
		protected var _split_alert : Alert;
		protected var _remove_alert : Alert;
		protected var _refs : Array;
		// 是否允许自动处理拖动
		public var dragActionHandler : Boolean = false;
		// 当拖动的时候是否已经把拖动的ui添加到场景中了
		protected var _isAddMouseIcon : Boolean = false;

		override protected function init() : void {
			_cell = _girdData.cell;
			_cells = new Array();
			_selectedCells = new Array();
			_refs = new Array();
			super.init();
		}

		override protected function create() : void {
			super.create();
			var templet : Cell = new _cell(_girdData.cellData);
			_cellWidth = templet.width;
			_cellHeight = templet.height;
			if (_data.scaleMode == ScaleMode.AUTO_SIZE) {
				_width = _cellWidth * _girdData.columns + (_girdData.columns - 1) * _girdData.hgap + _girdData.padding * 2;
				_height = _cellHeight * _girdData.rows + (_girdData.rows - 1) * _girdData.vgap + _girdData.padding * 2;
			}
			initCells();
			// 提示是否删除物品的ui
			if (_girdData.allowDrag) addAlerts();
		}

		protected function addAlerts() : void {
			_remove_alert = new Alert(_girdData.alertData);
			_remove_alert.addEventListener(Event.CLOSE, remove_closeHandler);
			var data : AlertData = _girdData.alertData.clone();
			data.labelData.text = "请输入拆分数量:";
			data.textInputData = new TextInputData();
			data.textInputData.borderAsset = new AssetData("show_show", "ui");
			data.textInputData.width = 150;
			data.textInputData.height = 25;
			data.textInputData.restrict = "0-9";
			data.textInputData.maxChars = 2;
			data.flag = Alert.OK | Alert.CANCEL;
			_split_alert = new _girdData.alert(data);
			_split_alert.addEventListener(Event.CLOSE, split_closeHandler);
		}

		// 添加格子ui
		protected function initCells() : void {
			_cells = new Array();
			var index : int = 0;
			for (var row : int = 0;row < _girdData.rows;row++) {
				for (var column : int = 0;column < _girdData.columns;column++) {
					var data : CellData = _girdData.cellData.clone();
					data.x = column * (_cellWidth + _girdData.hgap);
					data.y = row * (_cellHeight + _girdData.vgap);
					data.width = _cellWidth;
					data.height = _cellHeight;
					data.enabled = false;
					if (_girdData.hotKeys != null && index < _girdData.hotKeys.length) {
						data.hotKey = _girdData.hotKeys[index];
					}
					if (_model != null && _model.max > 0 && _cells.length >= _model.max) {
						data.lock = true;
					}
					var cell : Cell = new _cell(data);
					add(cell);
					_cells.push(cell);
					addCellEvents(cell);
					index++;
				}
			}
		}

		// 临时项目需要的方法  背包添加格子时候的
		protected function addCells(cellSize : int) : void {
			var index : int = 0;
			var nowRow : int = _cells.length / _girdData.columns;
			var newRow : int = cellSize / _girdData.columns + nowRow;
			for (nowRow ;nowRow < newRow ;nowRow++) {
				for (var column : int = 0;column < _girdData.columns;column++) {
					var data : CellData = _girdData.cellData.clone();
					data.x = column * (_cellWidth + _girdData.hgap);
					data.y = nowRow * (_cellHeight + _girdData.vgap);
					data.width = _cellWidth;
					data.height = _cellHeight;
					data.enabled = false;
					if (_girdData.hotKeys != null && index < _girdData.hotKeys.length) {
						data.hotKey = _girdData.hotKeys[index];
					}
					if (_model != null && _model.max > 0 && _cells.length >= _model.max) {
						data.lock = true;
					}
					var cell : Cell = new _cell(data);
					add(cell);
					_cells.push(cell);
					addCellEvents(cell);
					index++;
				}
			}
		}

		protected function updateCells(index : int = 0) : void {
			// 取出需要更新的cell
			var start : int = _pageModel.getPageIndex(index);
			var end : int = _girdData.expansionBag ? _cells.length : Math.min(_cells.length, _pageModel.currentSize);
			// Math.min(_cells.length, _pageModel.currentSize);
			var len : int = _cells.length;
			var cell : Cell;
			var base : int = _pageModel.base;
			for (var i : int = start;i < len;i++) {
				cell = _cells[i] as Cell;
				if (cell != null) cell.lock = (_model.max > 0 && (base + i) >= _model.max);
				if (i < end) {
					if (cell != null) cell.source = _model.getAt(base + i + _model.offset);
				} else {
					if (cell != null) cell.source = null;
				}
			}
		}

		// 添加cell的处理事件
		protected function addCellEvents(cell : Cell) : void {
			if (_girdData.cellData.allowDoubleClick) {
				cell.addEventListener(Cell.DOUBLE_CLICK, cell_doubleClickHandler);
			}
			cell.addEventListener(Cell.SINGLE_CLICK, cell_singleClickHandler);
			cell.addEventListener(CELL_MOVE, cell_dragHandler);
			cell.addEventListener(CELL_SPLIT, cell_splitHandler);
			cell.addEventListener(MouseEvent.MOUSE_UP, cell_Up);
			cell.addEventListener(MouseEvent.MOUSE_DOWN, cell_Down);
		}

		// 弹出分割物品的ui
		private function cell_splitHandler(event : Event) : void {
			if (_dragData.source.count > 1 && _dragData.source.max > 1) {
				_split_alert.show();
				GLayout.layout(_split_alert);
				_split_alert.source = _dragData.source;
				// _split_alert.moveTo(UIManager.root.stage.mouseX, UIManager.root.stage.mouseY);
				return;
			}
		}

		override protected function onHide() : void {
			super.onHide();
			if (_split_alert)
				_split_alert.hide();
			if (_dragImage != null) {
				dragEnd();
			}
		}

		private function cell_Up(event : MouseEvent) : void {
			var index : int = _cells.indexOf(event.currentTarget) + _model.offset ;
			if (index != -1) {
				_selectionModel.index = _pageModel.base + index;
			}
			// 判断是否需要快捷键
			if (Cell(event.currentTarget).ctrlKey) {
				dispatchEvent(event);
				return;
			}
			if (_girdData.allowDrag) {
				// 为cell添加事件
				UIManager.root.stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
				UIManager.root.stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
				_dragCell = Cell(event.currentTarget);
				if (_dragCell.toolTip != null) _dragCell.toolTip.hide();
				if (_dragCell is IDragSource && _dragCell.source is IDragItem) {
					// 取出cell的数据
					_dragData.reset(this, _dragCell.source);
					if (dragActionHandler) {
						dragStart();
					}
				}
			}
			dispatchEvent(event);
		}

		private function cell_dragHandler(event : Event) : void {
			if (_girdData.allowDrag) {
				_dragCell = Cell(event.currentTarget);
				if (!IDragSource(_dragCell).canDrag()) return;
				if (_dragCell.toolTip != null) _dragCell.toolTip.hide();
				if (_dragCell is IDragSource && _dragCell.source is IDragItem) {
					_dragData.reset(this, _dragCell.source);
					dragStart();
				}
			}
			dispatchEvent(new Event(Cell.SINGLE_CLICK));
		}

		private function cell_Down(event : Event) : void {
			if (_girdData.allowDrag) {
				_dragCell = Cell(event.currentTarget);
				if (_dragCell == null || _dragCell.source == null) return;
				if (!IDragSource(_dragCell).canDrag() || _dragCell == null || _dragCell.source == null) return;
				if (_dragCell.toolTip != null) _dragCell.toolTip.hide();
				_dragImage = IDragSource(_dragCell).dragImage;
				UIManager.dragData = _dragData;
				// 复制拖动的数据
				_dragData.reset(this, _dragCell.source);
				_isAddMouseIcon = false;
				UIManager.root.stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
				UIManager.root.stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
			}
		}

		/**
		 * 移除cell的事件
		 */
		protected function removeCellEvents(cell : Cell) : void {
			if (_girdData.cellData.allowDoubleClick) {
				cell.removeEventListener(Cell.DOUBLE_CLICK, cell_doubleClickHandler);
			}
			cell.removeEventListener(Cell.SINGLE_CLICK, cell_singleClickHandler);
			cell.removeEventListener(CELL_MOVE, cell_dragHandler);
			cell.removeEventListener(MouseEvent.MOUSE_DOWN, cell_dragHandler);
			cell.removeEventListener(MouseEvent.MOUSE_UP, cell_dragHandler);
		}

		/**
		 * 双击的处理
		 */
		protected function cell_doubleClickHandler(event : Event) : void {
			var index : int = _cells.indexOf(event.target) + _model.offset;
			if (index != -1) {
				_selectionModel.index = _pageModel.base + index;
			}
			dispatchEvent(event);
		}

		/**
		 * 单击的处理
		 */
		protected function cell_singleClickHandler(event : Event) : void {
			var index : int = _cells.indexOf(event.target) + _model.offset;
			if (index != -1 && _girdData.expansionBag) {
				_selectionModel.index = _pageModel.base + index;
			} else {
				_selectionModel.index = index;
			}
			// if (Cell(event.currentTarget).ctrlKey) {
			// dispatchEvent(event);
			// return;
			// }
			if (_girdData.allowDrag) {
				_dragCell = Cell(event.currentTarget);
				if (_dragCell.toolTip != null) _dragCell.toolTip.hide();
				if (_dragCell is IDragSource && _dragCell.source is IDragItem) {
					_dragData.reset(this, _dragCell.source);
					if (Cell(event.currentTarget).ctrlKey) {
						if (_dragData.source.count > 1 && _dragData.source.max > 1) {
							_split_alert.inputText = "1";
							_split_alert.source = _dragData.source;
							_split_alert.show();
							_split_alert.moveTo(UIManager.root.stage.mouseX, UIManager.root.stage.mouseY);
							return;
						}
					} else {
						if (dragActionHandler && _isAddMouseIcon) {
							dragStart();
						}
					}
				}
			}
			dispatchEvent(event);
		}

		/**\
		 * 当移动的时候去判断是否是拖动
		 */
		protected function stage_mouseMoveHandler(event : MouseEvent) : void {
			if (_isAddMouseIcon == false) {
				_dragCell.enabled = false;
				UIManager.dragModal = true;
				UIManager.root.stage.addChild(_dragImage);
				Mouse.hide();
				_isAddMouseIcon = true;
			}
			_dragImage.x = int(event.stageX - _dragImage.width * 0.5);
			_dragImage.y = int(event.stageY - _dragImage.height * 0.5);
		}

		override protected function stage_mouseUpHandler(event : MouseEvent) : void {
			UIManager.dragData = null;
			// 进行碰撞看看是碰到哪个可碰撞ui了
			var hitTarget : DisplayObject = UIManager.hitTest(UIManager.root.stage.mouseX, UIManager.root.stage.mouseY);
			if (_dragImage != null) {
				// 判断是否碰撞本ui
				if (UIManager.atParent(hitTarget, this)) {
					if (!_model.allowNull) {
						// 判断是否是拆分
						if (_dragData.split != null) {
							_dragData.source.count += _dragData.split.count;
						}
						dragEnd();
						return;
					}
					// 通过鼠标来判断是那个cell
					var c : int = _content.mouseX / (_girdData.cellData.width + _girdData.hgap);
					var r : int = _content.mouseY / (_girdData.cellData.height + _girdData.vgap);
					c = Math.max(0, Math.min(_girdData.columns - 1, c));
					if (!_girdData.enabled) r = Math.max(0, Math.min(_girdData.rows - 1, r));
					// r = Math.max(0, Math.min(_girdData.rows - 1, r));
					var index : int = _pageModel.base + r * _girdData.columns + c;
					_dragData.t_place = _model.place;
					_dragData.t_gird = index;
					if (_model.max > 0 && index >= _model.max) {
						if (_dragData.split != null) {
							_dragData.source.count += _dragData.split.count;
						}
						dragEnd();
						return;
					}
					// 取出数据
					var target : IDragItem = IDragItem(_model.getAt(index + _model.offset));
					if (target == null) {
						// 是否是分割
						if (_dragData.split == null) {
							if (dragActionHandler) {
								_model.setAt(_dragData.s_gird, null);
								_model.setAt(index + _model.offset, _dragData.source);
							} else {
								// 发出移动事件
								var e : DragUiEvent = new DragUiEvent(DragUiEvent.MOVE);
								e.source = _dragData.source;
								e.dest = target;
								// e.////sourceIndex = _dragData.s_gird;
								e.destIndex = index + _model.offset;
								dispatchEvent(e);
							}
						} else {
							if (dragActionHandler) {
								_model.setAt(index + _model.offset, _dragData.split);
							} else {
								// TODO 徐灿拆分  _dragData.split  IDragItem接口的  count拆分出来的数量;
								var splitEvent : DragUiEvent = new DragUiEvent(DragUiEvent.SPLIT);
								splitEvent.source = _dragData.source;
								splitEvent.splitCount = _dragData.split.splitCount;
								splitEvent.destIndex = index + _model.offset;
								dispatchEvent(splitEvent);
							}
							dragEnd();
						}
					} else {
						if (target == _dragData.source) {
							dragEnd();
							return;
						}
						if (_dragData.split == null) {
							if (target.merge(_dragData.source)) {
								if (_dragData.source.count == 0) {
									_model.setAt(_dragData.source.gird, null);
								}
							} else {
								if (dragActionHandler) {
									_model.setAt(_dragData.source.gird, target);
									_model.setAt(index + _model.offset, _dragData.source);
								} else {
									if (_cells[target.gird - _model.offset].canDrag()) {
										// 移动事件
										e = new DragUiEvent(DragUiEvent.MOVE);
										e.source = _dragData.source;
										e.dest = target;
										// e.////sourceIndex = _dragData.s_gird;
										e.destIndex = index + _model.offset;
										dispatchEvent(e);
									} else {
										_dragData.state = DragState.END;
									}
								}
							}
						} else {
							// /相同物品带数量的合并的处理
							if (!dragActionHandler) {
								var splitMergeEvent : DragUiEvent = new DragUiEvent(DragUiEvent.SPLIT_AND_MERGE);
								splitMergeEvent.source = _dragData.split;
								splitMergeEvent.dest = target;
								splitMergeEvent.destIndex = target.gird;
								splitMergeEvent.splitCount = _dragData.split.splitCount;
								dispatchEvent(splitMergeEvent);
							} else {
								if (target.merge(_dragData.split)) {
									if (_dragData.split.count > 0) {
										_dragData.source.count += _dragData.split.count;
									} else if (_dragData.source.count == 0) {
										_model.setAt(_dragData.source.gird, null);
									}
								} else {
									_dragData.source.count += _dragData.split.count;

									dragEnd();
									return;
								}
							}
						}
					}
				} else {
					_dragData.hitTarget = hitTarget;
					_dragData.stageX = UIManager.root.stage.mouseX;
					_dragData.stageY = UIManager.root.stage.mouseY;
					_dragModel.check(_dragData);
					// if (!dragActionHandler && _dragData.state == DragState.REMOVE || hitTarget == null) {
					if (!dragActionHandler && hitTarget == null) {
						var temp : DragUiEvent = new DragUiEvent(DragUiEvent.REMOVE);
						temp.source = _dragData.source;
						// temp.////sourceIndex = _dragData.s_place;
						dispatchEvent(temp);
						_dragData.state = DragState.END;
					}

					if (_dragData.state == DragState.NEXT) {
						return;
					}
					if (_dragData.state == DragState.END) {
						dragEnd();
						return;
					}
					if (_dragData.state == DragState.REMOVE && hitTarget == null) {
						dragEnd();
						var count : int = (_dragData.split == null ? _dragData.source.count : _dragData.splitCount);
						_remove_alert.label = "你真的要删除 [" + _dragData.source.name + "] " + count + "个?";
						// TODO  项目临时修改
						// _remove_alert.show();
						// GLayout.layout(_remove_alert);
						var temp2 : DragUiEvent = new DragUiEvent(DragUiEvent.REMOVE);
						temp2.source = _dragData.source;
						// temp.////sourceIndex = _dragData.s_place;
						dispatchEvent(temp2);
						return;
					}
					if (_dragData.state == DragState.MOVE) {
						if (_dragData.split == null) {
							_model.setAt(_dragData.s_gird, _dragData.target);
						}
					} else if (_dragData.state == DragState.MERGE) {
						if (_dragData.split == null && _dragData.source.count == 0) {
							_model.setAt(_dragData.s_gird, null);
						}
					} else if (_dragData.state == DragState.CANCEL) {
						if (_dragData.split != null) {
							_dragData.source.count += _dragData.split.count;
						}
					}
				}
				dragEnd();
				if (!dragActionHandler && target) {
				}
				// _dragData.source.syncMove(_dragData.s_place, _dragData.s_gird, _dragData.t_place, _dragData.t_gird, _dragData.split == null ? "" : _dragData.split.key, _dragData.splitCount);
			} else {
				if (!UIManager.atParent(hitTarget, this)) {
					var outside : Boolean = true;
					if (UIManager.atParent(hitTarget, _menuTrigger)) {
						outside = false;
					}
					if (outside) {
						hide();
					}
				}
			}
		}

		private function dragStart() : void {
			UIManager.dragModal = true;
			_dragCell.enabled = false;
			_dragImage = IDragSource(_dragCell).dragImage;
			_dragImage.x = int(UIManager.root.stage.mouseX - _dragImage.width * 0.5);
			_dragImage.y = int(UIManager.root.stage.mouseY - _dragImage.height * 0.5);
			UIManager.root.stage.addChild(_dragImage);
			UIManager.root.stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
			// if(!stage.hasEventListener(MouseEvent.MOUSE_UP)) {
			UIManager.root.stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
			// }
			Mouse.hide();
		}

		private function dragEnd() : void {
			UIManager.root.stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
			if (UIManager.root.stage.hasEventListener(MouseEvent.MOUSE_UP) && _menuTrigger == null) {
				UIManager.root.stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
			}
			UIManager.dragModal = false;
			if (_dragImage.parent) _dragImage.parent.removeChild(_dragImage);
			_dragData.split = null;
			if (_dragCell.source != null && _refs.indexOf(_dragCell.source) == -1) {
				_dragCell.enabled = true;
			}
			Mouse.show();
		}

		private function remove_closeHandler(event : Event) : void {
			var detail : uint = _remove_alert.detail;
			if (detail == Alert.YES) {
				if (_dragData.split == null) {
					_model.setAt(_selectionModel.index + _model.offset, null);
					IDragItem(_dragData.source).syncRemove();
				} else {
					IDragItem(_dragData.source).syncRemove(_dragData.split.count);
				}
			} else if (detail == Alert.NO) {
				if (_dragData.split != null) {
					_dragData.source.count += _dragData.split.count;
				}
			}
		}

		private function split_closeHandler(event : Event) : void {
			var detail : uint = _split_alert.detail;
			if (detail == Alert.OK) {
				var count : int = int(_split_alert.inputText);
				count = Math.max(0, Math.min(_dragData.source.count, count));
				if (count <= 0) {
					return;
				} else if (count < _dragData.source.count) {
					_dragData.split = _dragData.source.split(count);
					if (_model.findFree()) {
						var splitEvent : DragUiEvent = new DragUiEvent(DragUiEvent.SPLIT);
						splitEvent.source = _dragData.source;
						splitEvent.splitCount = _dragData.split.splitCount;
						splitEvent.destIndex = _model.findFree();
						dispatchEvent(splitEvent);
					}
					// _dragData.splitCount = count;
					// dragStart();
				} else {
					dragStart();
				}
			}
		}

		protected function model_changeHandler(event : ListEvent) : void {
			var cell : Cell;
			var state : int = event.state;
			var index : int = event.index;
			var item : Object = event.item;
			var oldItem : Object = event.oldItem;
			switch(state) {
				case ListState.RESET:
					updateCells();
					if (_selectionModel.index >= _model.size) _selectionModel.index = -1;
					break;
				case ListState.ADDED:
					if (!_pageModel.atCurrentPage(index)) return;
					cell = _cells[_pageModel.getPageIndex(index)] as Cell;
					if (cell) cell.source = item;
					break;
				case ListState.REMOVED:
					if (!_pageModel.atCurrentPage(index)) return;
					updateCells(index);
					if (index < _selectionModel.index) {
						_selectionModel.index -= 1;
					} else if (index == _selectionModel.index) {
						_selectionModel.index = -1;
					}
					break;
				case ListState.UPDATE:
					if (!_girdData.expansionBag && !_pageModel.atCurrentPage(index - _model.offset)) return;
					// cell = _cells[_pageModel.getPageIndex(index - _model.offset)] as Cell;
					cell = _girdData.expansionBag ? _cells[index - _model.offset] as Cell : _cells[_pageModel.getPageIndex(index - _model.offset)] as Cell;
					if (cell != null) {
						cell.source = item;
						if (cell.source != null && _refs.indexOf(cell.source) != -1) {
							cell.enabled = false;
						}
					}
					var i : int = _refs.indexOf(oldItem);
					if (oldItem != null && i != -1) {
						_refs.splice(i, 1);
					}
					if (item == null && _selectionModel.index == index) {
						_selectionModel.index = -1;
					}
					break;
				case ListState.INSERT:
					if (!_pageModel.atCurrentPage(index)) return;
					updateCells(index);
					if (index <= _selectionModel.index) _selectionModel.index += 1;
					break;
			}
		}

		protected function page_changeHandler(event : Event) : void {
			updateCells(_pageModel.base);
			resetSelected();
		}

		protected function selection_changeHandler(event : Event) : void {
			resetSelected();
		}

		protected function resetSelected() : void {
			var cell : Cell;
			for each (cell in _selectedCells) {
				cell.selected = false;
			}
			_selectedCells.splice(0);
			if (!_pageModel.atCurrentPage(_selectionModel.index)) return;
			cell = _cells[_selectionModel.index] as Cell;

			if (cell) {
				cell.selected = true;
				_selectedCells.push(cell);
			}
		}

		protected function addModelEvents() : void {
			_model.addEventListener(ListEvent.CHANGE, model_changeHandler);
			_model.addEventListener(Event.RESIZE, modeMaxChangeHandler);
			if (_girdData.cellData.allowSelect) {
				_selectionModel.addEventListener(Event.CHANGE, selection_changeHandler);
			}
		}

		private function modeMaxChangeHandler(event : Event) : void {
			if (_model.max > _cells.length && _girdData.expansionBag) {
				addCells(_model.max - _cells.length);
			}
		}

		protected function removeModelEvents() : void {
			_model.removeEventListener(ListEvent.CHANGE, model_changeHandler);
			_model.removeEventListener(Event.RESIZE, modeMaxChangeHandler);
			if (_girdData.cellData.allowSelect) {
				_selectionModel.removeEventListener(Event.CHANGE, selection_changeHandler);
			}
		}

		public function Gird(data : GirdData) {
			_girdData = data;
			super(data);
			_selectionModel = new SelectionModel();
			_dragModel = new DragModel();
			_dragData = new DragData();
			_model = new ListModel(true, _girdData.rows * _girdData.columns);
			_pageModel = new PageModel(_girdData.rows * _girdData.columns, _model);
			_pageModel.addEventListener(PageModel.PAGE_CHANGE, page_changeHandler);
			addModelEvents();
		}

		public function get selectionModel() : SelectionModel {
			return _selectionModel;
		}

		public function get dragModel() : DragModel {
			return _dragModel;
		}

		public function get pageModel() : PageModel {
			return _pageModel;
		}

		public function set model(value : ListModel) : void {
			if (_model != null) {
				removeModelEvents();
			}
			_model = value;
			_pageModel.listModel = model;

			if (_model != null) {
				addModelEvents();
				_model.update();
				if (_model.max > _cells.length && _girdData.expansionBag) {
					addCells(_model.max - _cells.length);
				}
			}
		}

		public function get model() : ListModel {
			return _model;
		}

		public function getCellBy(value : int) : Cell {
			return _cells[value];
		}

		public function indeOfCell(cell : Cell) : int {
			return _cells.indexOf(cell);
		}

		public function getCellSize() : int {
			return _cells.length;
		}

		public function get selectionCell() : Cell {
			return _cells[_selectionModel.index - _model.offset];
		}

		public function get selection() : Object {
			return _model.getAt(_selectionModel.index + _model.offset);
		}

		// 别的物品拖动过来的处理
		public function dragEnter(dragData : DragData) : Boolean {
			if (!UIManager.atParent(dragData.hitTarget, this)) {
				return false;
			}
			var local : Point = globalToLocal(new Point(dragData.stageX, dragData.stageY));
			local.x += _content.scrollRect.x;
			local.y += _content.scrollRect.y;
			var c : int = (local.x - _girdData.padding) / (_girdData.cellData.width + _girdData.hgap);
			var r : int = (local.y - _girdData.padding) / (_girdData.cellData.height + _girdData.vgap);
			// c = Math.max(0, Math.min(_girdData.columns - 1, c));
			// r = Math.max(0, Math.min(_girdData.rows - 1, r));
			var index : int = _pageModel.base + r * _girdData.columns + c;
			dragData.t_place = _model.place;
			dragData.t_gird = index;
			if (_model.max != -1 && index >= _model.max) {
				dragData.state = DragState.CANCEL;
				return true;
			}
			var target : IDragItem = _model.getAt(index + _model.offset) as IDragItem;
			if (target == null) {
				if (dragActionHandler) {
					// 发出移动事件
					dragData.state = DragState.MOVE;
					_model.setAt(index + _model.offset, dragData.split == null ? dragData.source : dragData.split);
					return true;
				} else {
					// 无用老的自动处理流程
					var e : DragUiEvent = new DragUiEvent(DragUiEvent.ADD);
					e.source = dragData.source;
					e.destIndex = index + _model.offset;
					dispatchEvent(e);
					dragData.state = DragState.END;
					return true;
				}
			} else {
				if (dragData.split == null) {
					if (target.merge(dragData.source)) {
						dragData.state = DragState.MERGE;
						return true;
					}
					if (dragData.owner.canSwap(dragData.source, target)) {
						if (dragActionHandler) {
							// 移动事件
							_model.setAt(index + _model.offset, dragData.source);
							dragData.state = DragState.MOVE;
							dragData.target = target;
							return true;
						} else {
							// 无用老的自动处理方法
							var event : DragUiEvent = new DragUiEvent(DragUiEvent.MOVE);
							event.source = dragData.source;
							event.dest = target;
							dispatchEvent(event);
							dragData.state = DragState.END;
							return true;
						}
					}
					dragData.state = DragState.CANCEL;
					return true;
				} else {
					if (target.merge(dragData.split)) {
						if (dragData.split.count > 0) {
							dragData.source.count += dragData.split.count;
						}
						dragData.state = DragState.MERGE;
						return true;
					}
					dragData.state = DragState.CANCEL;
					return true;
				}
			}
			return true;
		}

		// 是否允许交换
		public function canSwap(source : IDragItem, target : IDragItem) : Boolean {
			return true;
		}

		public function addRef(value : Object) : void {
			if (_refs.indexOf(value) != -1) {
				return;
			}
			_refs.push(value);
			var cell : Cell;
			cell = getCellBy(_model.indexOf(value));
			if (cell != null) {
				cell.enabled = false;
			}
		}

		public function removeRef(value : Object) : void {
			var index : int = _refs.indexOf(value);
			if (index == -1) {
				return;
			}
			_refs.splice(index, 1);
			var cell : Cell;
			cell = _cells[_model.indexOf(value)];
			if (cell != null) {
				cell.enabled = true;
			}
		}

		public function getRefs() : Array {
			return _refs;
		}

		public function get cells() : Array {
			return _cells;
		}
	}
}
